package org.ccay.excel.importer.internal.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.inject.Named;

import org.apache.commons.vfs2.FileObject;
import org.ccay.async.task.ImportTaskVO;
import org.ccay.core.base.KeyValuePairVO;
import org.ccay.core.exception.ApplicationException;
import org.ccay.core.io.VFSFileObject;
import org.ccay.core.log.CcayLoggerFactory;
import org.ccay.core.log.ILogger;
import org.ccay.core.util.JsonUtil;
import org.ccay.core.util.PathUtil;
import org.ccay.core.util.StringUtil;
import org.ccay.excel.exception.ExcelSystemException;
import org.ccay.excel.importer.service.IExcelImportAssistant;
import org.ccay.excel.importer.service.IExcelImportSupport;
import org.ccay.registry.exception.RegistryNotFindException;
import org.ccay.registry.util.RegistryQueryUtil;
import org.ccay.upload.FolderSplitType;
import org.ccay.upload.IUploadFileConsumer;
import org.ccay.upload.UploadSettingVO;
import org.ccay.vfs.VFS;

/**
 * 导入文件的消费者，处理导入事件	
 * @author chaowangbang
 * @since 2012-2-9
 */
@Named("IUploadFileConsumer.ExcelImport")
public class ExcelUploadConsumer implements IUploadFileConsumer {
	/**
	 * 导入不被支持
	 */
	public static final String IMPORT_NOT_SUPPORT = "ccay.excel.00080001";

	/**
	 * 日志组件
	 */
	private static final ILogger logger = CcayLoggerFactory.getLogger(ExcelUploadConsumer.class);
	/**
	 * 存储Registry的前缀
	 */
	private static final String BASE_PATH = "App.Excel.";

	/**
	 * 最大使用的内存
	 */
	private static final int MAX_MEMORY = 1024*1024*2;
	/**
	 * 最大文件大小
	 */
	private static final long MAX_SIZE = 1024*1024*20;
	/**
	 * 最大文件数
	 */
	private static final int MAX_COUNT = 5;
	
	/**
	 * 上传模块的保存目录扩容数据字典序列配置Dilatancy
	 */
	private static final String SO_DILATANCY_PATH = "Ccay.GlobalParamters";

	/**
	 * Excel 导入助理
	 */
	@Inject
	private IExcelImportAssistant assistant;
	/* (non-Javadoc)
	 * @see org.ccay.upload.support.IUploadFileConsumer#getUploadSetting()
	 */
	@Override
	public UploadSettingVO getUploadSetting(Map<String, String> parameters){
		UploadSettingVO setting = new UploadSettingVO();
		String excelType = formatExcelType(getExcelType(parameters));
		setting.setFileSplitType(FolderSplitType.ByDay);
		setting.setFileTypesAllowed(Arrays.asList(new String[]{"xlsx","xlsm"}));
		setting.setMaxFileCount(getMaxFileCount(excelType));
		setting.setMaxFileSize(getMaxFileSize(excelType));
		setting.setMaxMemory(getMaxMemory(excelType));
		setting.setVfsModule("excel");
		return setting;
	}

	@Override
	public Object processFiles(Map<String, String> parameters,
			List<VFSFileObject> fileInfos) throws ApplicationException {
		String excelType = getExcelType(parameters);
		List<KeyValuePairVO> results = new ArrayList<KeyValuePairVO>();
		for(VFSFileObject file :fileInfos){	
			//逐个处理，以便支持多个Excel的处理
			ImportTaskVO task = assistant.submitImportTask(file,excelType, parameters);
			String taskId = String.valueOf(task.getTaskId());
			results.add(new KeyValuePairVO(task.getDisplayFileName(), taskId));
			
			String taskJson = null;
			try {
				task.setFilePath("");
				taskJson = JsonUtil.getJsonString(task);
				logger.debug("Trans task object to json format : {0}", taskJson);
			} catch (IOException e) {
				logger.debug("Occur error when trans task object to json format.", e);
			}
			results.add(new KeyValuePairVO(taskId,taskJson));
			
			logger.debug("To delete VFS fileObject : {0}", file.getURI());
			file.delete();
			file.close();
		}
		
		return results;
	}

	/** 
	 * 从Request参数中获取ExcelType
	 * @param parameters
	 * @return
	 */
	private String getExcelType(Map<String, String> parameters) {
		//未指定excel类型，无法处理
		if(!parameters.containsKey("excelType")){
			throw new ExcelSystemException(IMPORT_NOT_SUPPORT,
			"No excel type found in parameters.");
		}
		String excelType =  parameters.get("excelType");
		return excelType;
	}

	/* (non-Javadoc)
	 * @see org.ccay.upload.support.IUploadFileConsumer#validatePrivilege(java.util.Map)
	 */
	public boolean validatePrivilege(Map<String, String> parameters) {
		String excelType = getExcelType(parameters);
		IExcelImportSupport importSupport = assistant.getImportSupport(excelType);
		//将验证权限交给IExcelImportSupport完成
		return importSupport.validatePrivilege();
	} 
	
	/** 
	 * 最大使用的内存
	 * @param excelType 附件类型
	 * @return
	 * @throws ApplicationException 
	 */
	private int getMaxMemory(String excelType) {
		String registryPath = BASE_PATH + excelType +".maxMemory";
		try{
			return RegistryQueryUtil.getIntegerValue(registryPath);
		}catch (RegistryNotFindException e) {
			return MAX_MEMORY;
		}
		 
	}

	/** 
	 * 获取最大文件大小
	 * @param excelType
	 * @return 
	 * @throws ApplicationException 
	 */
	private long getMaxFileSize(String excelType) {
		String registryPath = BASE_PATH + excelType +".maxSize";
		try{
			return RegistryQueryUtil.getLongValue(registryPath);
		}catch (RegistryNotFindException e) {
			return MAX_SIZE;
		}
	}

	/** 
	 * 获取最多文件个数
	 * @param excelType
	 * @return
	 * @throws ApplicationException 
	 */
	private int getMaxFileCount(String excelType) {
		String registryPath = BASE_PATH + excelType +".maxCount";
		try{
			return RegistryQueryUtil.getIntegerValue(registryPath);
		}catch (RegistryNotFindException e) {
			return MAX_COUNT;
		}
	}
	
	/**
	 * 
	 * @param excelType
	 * @return
	 */
	private String formatExcelType(String excelType){
		String[] types = excelType.split("\\.");
		StringBuffer sb = new StringBuffer();
		for(String type : types){
			//将第一字母大写
			sb.append(StringUtil.firstUpperCase(type));
		}
		return sb.toString();
	}
	
	/**
	 * 获取数据字典的配置，01为默认不配置使用AppName
	 * @return
	 * 
	 */   
	private String getSoDilatancyPath(){
		//检查数据字典的配置，01为默认值，则dm上传模块的保存目录为appname
		return RegistryQueryUtil.getValue(SO_DILATANCY_PATH+".SoDirIndex");
	}
}
